import { BufferGeometry, DoubleSide, EdgesGeometry, Float32BufferAttribute, FrontSide, LineBasicMaterial, LineSegments, Mesh, MeshPhongMaterial, MeshPhongMaterialParameters } from "three";


export default class EntityBase implements IDispose{

    protected _mesh:Mesh;

    protected _frameLine:LineSegments;

    get mesh(): Mesh {
        return this._mesh;
    }

    constructor(vertices: number[], indices: number[], color: any, isCenter:boolean = false) {
        // 几何
        const geo = new BufferGeometry();
        geo.setIndex(indices);
        geo.setAttribute('position', new Float32BufferAttribute(vertices, 3));
        // 材质参数
        const matparams: MeshPhongMaterialParameters = {
            color: color,
            side: DoubleSide,
            // specular: 0xffffff,
        }
        // 计算法线
        geo.computeVertexNormals();
        // 
        isCenter ? geo.center() : null;
        // 材质
        const mat = new MeshPhongMaterial(matparams);
        // mesh
        this._mesh = new Mesh(geo, mat);

        // 边框
        const edges = new EdgesGeometry(geo);
        this._frameLine = new LineSegments(edges, new LineBasicMaterial({
            color:0x000000,
        }));

        this._mesh.add(this._frameLine);
    }

    updateGeometry(vertices: number[], indices: number[]) {
        this._mesh.geometry.attributes.normal = undefined;
        this._mesh.geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
        this._mesh.geometry.setIndex(indices);
        this._mesh.geometry.computeVertexNormals();

        this.updateWareFrame();
    }

    updateWareFrame(): void {

        if(this._frameLine){
            this._mesh.remove(this._frameLine);
            this._frameLine.geometry && this._frameLine.geometry.dispose();
            this._frameLine.material && (this._frameLine.material as LineBasicMaterial).dispose();
            this._frameLine = null;
        }

        const edges = new EdgesGeometry(this._mesh.geometry);
        this._frameLine = new LineSegments(edges, new LineBasicMaterial({
            color:0x000000,
        }));

        this._mesh.add(this._frameLine);
    }


    dispose(): void {

        if(this._mesh) {
            this._mesh.geometry && this._mesh.geometry.dispose();
            this._mesh.material && (this._mesh.material as MeshPhongMaterial).dispose();
            this._mesh = null;

            if(this._frameLine){
                this._mesh.remove(this._frameLine);
                this._frameLine.geometry && this._frameLine.geometry.dispose();
                this._frameLine.material && (this._frameLine.material as LineBasicMaterial).dispose();
                this._frameLine = null;
            }
        }
        
    }
}